#include "webspideraround.h"
#include "webcollector.h"

#include <QDebug>

WebSpiderRequestManager* WebSpiderRequestManager::m_instance = NULL;

WebSpiderRequestManager* WebSpiderRequestManager::instance()
{
    if(!m_instance)
        m_instance = new WebSpiderRequestManager();
    return m_instance;
}

WebSpiderRequest* WebSpiderRequestManager::startRequest (
        QString url, QString name, QVariantList cookies,
        int level, long timeoutTime, long destroyTimeMs
        )
{
    if (isUrlInHistory(url))
        m_history.push_back(url);
    WebSpiderRequest *req = new WebSpiderRequest(url, name);
    req->setLevel(level);
    req->setSelfDestroyTime(destroyTimeMs);
    req->setTimeoutTime(timeoutTime);
    req->setCookies(cookies);

    req->fire();
    return req;
}

WebSpiderRequest* WebSpiderRequestManager::createRequest (
        QString url, QString name,
        int level, long timeoutTime, long destroyTimeMs
        )
{
    if (isUrlInHistory(url))
        m_history.push_back(url);
    WebSpiderRequest *req = new WebSpiderRequest(url, name);
    req->setLevel(level);
    req->setSelfDestroyTime(destroyTimeMs);
    req->setTimeoutTime(timeoutTime);

    return req;
}

WebSpiderSyncRequest* WebSpiderRequestManager::createSyncRequest (
        QString url, QString name,
        int level, long timeoutTime, long destroyTimeMs
        )
{
    if (isUrlInHistory(url))
        m_history.push_back(url);
    WebSpiderSyncRequest *req = new WebSpiderSyncRequest(url, name);
    req->setLevel(level);
    req->setSelfDestroyTime(destroyTimeMs);
    req->setTimeoutTime(timeoutTime);

    return req;
}

bool WebSpiderRequestManager::isUrlInHistory(QString url)
{
    if (m_history.contains(url))
        return true;
    return false;
}

WebSpiderRequest::WebSpiderRequest(QString url, QString spiderName)
    : m_url(url)
    , m_name(spiderName)
    , m_id(QString::number(reinterpret_cast<intptr_t>(this)))
    , m_level(100)
    , m_selfDestroyTimeMS(0)
{
}

WebSpiderRequest::~WebSpiderRequest()
{
}

void WebSpiderRequest::setLevel(int level)
{
    m_level = level;
}

int WebSpiderRequest::level()
{
    return m_level;
}

void WebSpiderRequest::parse(Operator *opt)
{
    WebCollector::instance()->getSpider(spiderName())->parse(opt);
}

void WebSpiderRequest::remove(Operator *opt)
{
    WebCollector::instance()->getSpider(spiderName())->removeSuccessOpt(opt);
}

void WebSpiderRequest::fire()
{
    WebCollector::instance()->newActivite(this);
}

void WebSpiderRequest::setSelfDestroyTime(long timeMS)
{
    m_selfDestroyTimeMS = timeMS;
}

void WebSpiderRequest::setTimeoutTime(long timeMS)
{
    m_timeoutMs = timeMS;
}

void WebSpiderRequest::setClientID(std::string clientid)
{
    m_clientID = clientid;
}

std::string WebSpiderRequest::clientID()
{
    return m_clientID;
}

void WebSpiderRequest::appendResourceFilterRule(QString rule)
{
    m_resourcesFilter.push_back(rule);
}

void WebSpiderRequest::appendResourceFilterRule(QList<QString> rules)
{
    QList<QString>::iterator it;
    for (it = rules.begin(); it != rules.end(); it++) {
        appendResourceFilterRule(*it);
    }
}

void WebSpiderRequest::setResourceFilterRule(QList<QString> rules)
{
    m_resourcesFilter.clear();
    appendResourceFilterRule(rules);
}

void WebSpiderRequest::removeResourceFilterRule(QString rule)
{
    m_resourcesFilter.removeOne(rule);
}

QList<QString> WebSpiderRequest::resourceFilterRules()
{
    return m_resourcesFilter;
}

void WebSpiderRequest::setCookies(QVariantList cookies)
{
    m_cookies = cookies;
}

QVariantList WebSpiderRequest::getCookies()
{
    return m_cookies;
}

WebSpiderSyncRequest::WebSpiderSyncRequest(QString url, QString spiderName)
    : WebSpiderRequest(url, spiderName)
    , m_opt(NULL)
{
    connect(&m_waitTimer, SIGNAL(timeout()), this, SLOT(onTimeout())); 
}

void WebSpiderSyncRequest::stopWaitTimer()
{
    if (m_waitTimer.isActive())
        m_waitTimer.stop();
}

void WebSpiderSyncRequest::startWaitTimer(long timeMS)
{
    if (timeMS <= 0)
        return;

    if (m_waitTimer.isActive())
        return;

    m_waitTimer.start(timeMS);
    m_waitTimer.setSingleShot(true);
}

void WebSpiderSyncRequest::onTimeout()
{
    if (!m_opt)
        return ;

    qDebug() << "spider sync request timeout.";
    m_opt->clearLoadSuccess();
    m_opt->setTimeout();

    WebCollector::instance()->getSpider(spiderName())->parse(m_opt);
}

WebSpiderDownloadRequest::WebSpiderDownloadRequest(Operator *opt, QString clientid, QString spiderName, long ref, int timeout)
    : m_opt(opt)
    , m_spiderName(spiderName)
    , m_success(false)
    , m_clientID(clientid)
    , m_downloadElementRef(ref)
    , m_contentType("application/octet-stream")
{
    m_waitTimer.start(timeout);
    m_waitTimer.setSingleShot(true);
}

long WebSpiderDownloadRequest::ref()
{
    return m_downloadElementRef;
}

void WebSpiderDownloadRequest::setSuccess()
{
    m_success = true;
}

bool WebSpiderDownloadRequest::success()
{
    return m_success;
}

void WebSpiderDownloadRequest::setLink(QString link)
{
    m_link = link;
}

QString WebSpiderDownloadRequest::link()
{
    return m_link;
}

QString WebSpiderDownloadRequest::clientID()
{
    return m_clientID;
}

void WebSpiderDownloadRequest::setHeaders(QVariantList headers)
{
    m_headers = headers;
}

QVariantList WebSpiderDownloadRequest::headers()
{
    return m_headers;
}

void WebSpiderDownloadRequest::setContentType(QString ctype)
{
    m_contentType = ctype;
}

QString WebSpiderDownloadRequest::contentType()
{
    return m_contentType;
}

void WebSpiderDownloadRequest::end()
{
    if (m_waitTimer.isActive())
        m_waitTimer.stop();
    WebCollector::instance()->getSpider(m_spiderName)->sendDownloadInfo(m_opt);
}

void WebSpiderDownloadRequest::onTimeout()
{
    if (!m_opt)
        return ;
    WebCollector::instance()->getSpider(m_spiderName)->sendDownloadInfo(m_opt);
}

void WebSpiderAround::parse(Operator *opt)
{
    opt->stopTimeoutTimer();
    m_request->parse(opt);
}

void WebSpiderAround::remove(Operator *opt)
{
    m_request->remove(opt);
}

